/*! \file list.h
	\author HiddenSeeker

	Defines a list node
*/
#include "../abstractnode.h"
#include <vector>
#pragma once


template<
typename _nodeType
>
class ListNode: public AbstractNode
{
 private:
	     std::vector<_nodeType *> m_vector;
		 const char *             m_type_string;
 public:
	     ListNode(const YYLTYPE & pos, const char * tname): AbstractNode(pos)
		 {
           m_type_string= tname;
		 }
		 _nodeType * add(_nodeType * n) 
		 { 
			 if (!n) return n;
			 if (m_vector.size()==0)
			 {
				 line()=n->line();
				 position()=n->position();
			 }
			 m_vector.push_back(n); 
			 return n;
		 }
		 inline const std::vector<_nodeType *> & vector() const { return m_vector; }
		 inline  std::vector<_nodeType *> & vector()  { return m_vector; }
		 void write(GraphStream * s)
		 {
			 this->accept(s);
			 fprintf(s->stream,"\tnode_%d [ label=\"(%d,%d)\\n ListNode<%s>\" shape=\"rectangle\"]\n",this->number(),m_line,m_pos,m_type_string);
			 for(unsigned int i=0;i<m_vector.size();i++)
			 {
				 m_vector[i]->write(s);
				 fprintf(s->stream, "\tnode_%d -> node_%d\n",this->number(),m_vector[i]->number());
			 }
		 }
		 /*! Fills a constant table for method
		 */
		virtual void fillConstant(ParentData * data)
		{
			for (unsigned  int i=0;i<m_vector.size();i++)
				m_vector[i]->fillConstant(data);
		}

		/*! Produces a code for method
		 */
		virtual void produceCode(ParentData * data)
		{
			for (unsigned int i=0;i<m_vector.size();i++)
				m_vector[i]->produceCode(data);
		}
		 
		~ListNode()
		 {
			 if (isOwningData())
			 {
				 for (unsigned int i=0;i<m_vector.size();i++)
					 delete m_vector[i];
			 }
		 }
};


/*! \def CREATE_LIST(POS,TYPE)
    Creates a list node
*/
#define CREATE_LIST(POS,TYPE) new ListNode< TYPE >(POS, #TYPE )

